<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://best.openssf.org/assets/css/style.css">
<link rel="stylesheet" href="checker.css">
<script src="checker.js"></script>
<script src="handling-errors.js"></script>
<link rel="license" href="https://creativecommons.org/licenses/by/4.0/">

<!-- See create_labs.md for how to create your own lab! -->

</head>
<body>
<!-- For GitHub Pages formatting: -->
<div class="container-lg px-3 my-5 markdown-body">
<h1>ラボ演習 handling-errors</h1>
<p>
これはセキュアなソフトウェア開発に関するラボ演習です。
ラボの詳細については、<a href="ja_introduction.html" target="_blank">概要</a>をご覧ください。
  
<p>
<h2>タスク</h2>
<p>
<b>例外処理の仕組みを活用して、下記のコードの堅牢性を高めましょう。</b>

<p>
<h2>背景</h2>
<p>
この演習では、リターンコードの仕組みから例外処理に移行することで、JavaScriptの関数の堅牢性をどのように高めるかを例示します。
一番の目標はエラーをより効果的に対処する方法を理解することで、これによりコードの可読性やメンテナンス性を高めることができます。
</p>
最初に、このコードは、起こりうるエラーを対処するために、リターンコードの仕組みを用いています。
<tt>divide</tt>関数は、処理が成功したかエラーが起きたかを表すオブジェクトを返します。
呼び出し元では、successプロパティをチェックして、正常な結果かエラーにそれぞれ対処する必要があります。
この方法でも動作はしますが、エラーをチェックするロジックが繰り返されてコードが汚くなりかねません。なお悪いことに、呼び出し元がエラーというリターンコードを無視してしまうと、予期しない失敗やセキュリティ脆弱性を引き起こすことすらありえます。

<p>
<h2>タスクの詳細</h2>
<p>
  
以下のコードを修正して、例外ハンドリングの仕組みを活用し堅牢性を高めてください。
</p>
不正な処理が検出されたとき(この場合は、0で割ったとき)例外を投げることによって、コードの正常フローとエラー処理のロジックを分離することができます。呼び出し元はtry..catchブロックを用いて、投げられる可能性のある例外を処理することができます。これによってコードがよりきれいになり、より堅牢となります。
</p>
このタスクを完了するには、以下を行います。
</p>
<ol>
<li>コードの中で成功か失敗かを表すのにリターンコードを使っている関数を見つけます。今回の例では、<tt>divide</tt>関数です。</li>
<li>その関数を、不正な処理を検出した場合にエラーを投げるように変更します。今回の例では、パラメータ<tt>b</tt>が0のときにエラーを投げるようにします。</li>
<li>エラーメッセージを"Division by zero is forbidden"(「0による割り算は禁止されています」)にします。</li>
<li>成功パスを、割り算の結果を返すように変更します。</li>
<li>呼び出しているコードを、<tt>divide</tt>関数呼び出しの回りをtryブロックで囲むように変更します。</li>
<li>tryブロックの中で、エラーが投げられなかった場合は割り算の結果を記録するようにします。</li>
<li>catchブロックを追加し、<tt>divide</tt>関数から投げられたエラーを処理するようにします。</li>
<li>成功パスでもエラーパスでも、コンソールやエラーコンソールに適切なメッセージを表示するようにします。</li>
</ol>
<p>
必要に応じて、「ヒント」ボタンと「諦める」ボタンを使用してください。
<p>
<h2>演習 (<span id="grade"></span>)</h2>
<p>
下記のコードを変更して、<tt>divide</tt>関数とその呼び出し元がリターンコードの仕組みではなく例外ハンドリングを用いるように変更してください。
<tt>divide</tt>関数は、0による割り算が行われようとした時にエラーを投げなければなりません。
呼び出すコードは、try...catchブロックを用いてエラーを処理し、<tt>result</tt>という定数に結果を格納し、発生したエラーは<tt>error</tt>という変数に受け、適切なメッセージを表示しなければなりません。

<form id="lab">
<pre><code>// a/bの結果を返すシンプルな割り算メソッドの実装
function divide(a, b) {
  if (b === 0) {
    <input id="attempt0" type="text" size="70" spellcheck="false"
 value='return { success: false, message: "Division by zero is forbidden" };'>
  } else {
    <input id="attempt1" type="text" size="70" spellcheck="false"
 value='return { success: true, result: a / b };'>
  }
}

// divide関数を呼び出し、結果かエラーを表示する
<textarea id="attempt2" rows="8" cols="60" spellcheck="false">
const result = divide(10, 2);
if (result.success) {
  console.log("Result:", result.result);
} else {
  console.error("Error:", result.message);
}
</textarea></code></pre>
<button type="button" class="hintButton">ヒント</button>
<button type="button" class="resetButton">リセット</button>
<button type="button" class="giveUpButton">諦める</button>
<br><br>
<p>
<i>このラボは<a href="https://www.microsoft.com/">Microsoft</a>のAvishay Balterによって開発されました。</i>
<br><br>
<p id="correctStamp" class="small">
<textarea id="debugData" class="displayNone" rows="20" cols="65" readonly>
</textarea>
</form>
</div><!-- End GitHub pages formatting -->
</body>
</html>
